<?php
Zend_Loader::loadClass('Lead_Db_Adapter_Interface');
Zend_Loader::loadClass('Zend_Db_Adapter_Pdo_Mysql');

/**
 * Lead_Db PDO/Mysql adapter.
 * 
 * @category Lead
 * @package Db 
 * 
 */
class Lead_Db_Adapter_Pdo_Mysql extends Zend_Db_Adapter_Pdo_Mysql implements Lead_Db_Adapter_Interface
{

    private static $nativeToCommonMap = array
	(
		'tinyint' => array('type' => 'tinyint', 'options' => array()),
	    'smallint' => array('type' => 'smallint', 'options' => array()),
		'int' => array('type' => 'integer', 'options' => array()),
		'bigint' => array('type' => 'bigint', 'options' => array()),
		'varchar' => array('type' => 'string', 'options' => array()),
		'char' => array('type' => 'char', 'options' => array()),
		'text' => array('type' => 'text', 'options' => array()),
		'date' => array('type' => 'date', 'options' => array()),
		'timestamp' => array('type' => 'datetime', 'options' => array()),
		'real' => array('type' => 'single', 'options' => array()),
		'double' => array('type' => 'double', 'options' => array()),
		'tinyint(1)' => array('type' => 'boolean', 'options' => array())
	);

	private static $commonToNativeMap = array(
		'tinyint' => array('type' => 'tinyint', 'options' => array()),
	   'smallint' => array('type' => 'smallint', 'options' => array()),
		'integer' => array('type' => 'integer', 'options' => array()),
		'bigint' => array('type' => 'bigint', 'options' => array()),
		'string' => array('type' => 'character varying', 'options' => array('size' => 255)),
		'char' => array('type' => 'character', 'options' => array()),
		'text' => array('type' => 'text', 'options' => array()),
		'date' => array('type' => 'date', 'options' => array()),
		'datetime' => array('type' => 'datetime', 'options' => array()),
		'single' => array('type' => 'single', 'options' => array()),
		'double' => array('type' => 'double', 'options' => array()),
		'boolean' => array('type' => 'boolean', 'options' => array())
	);


	public static function nativeToCommon($columns)
	{
	    foreach($columns as &$column)
	    {
	        if(key_exists($column['DATA_TYPE'], self::$nativeToCommonMap))
                $column['DATA_TYPE'] = self::$nativeToCommonMap[$column['DATA_TYPE']]['type'];
	    }
	    return $columns;
	}
    
    
	public function nextId($sequenceName)
    {

    	$seqname = "{$sequenceName}_seq";
        do {
            $repeat = 0;


            try {
                $result = $this->query('UPDATE ' . $seqname . ' SET id = LAST_INSERT_ID(id + 1)');
            }
            catch(Zend_Db_Statement_Exception $e) {
                return $this->createSequence($seqname);
            }


            if($result)
            {
            	$id = $this->lastInsertId();
            	if ($id != 0) {
                    return $id;
                }



             	$result = $this->fetchOne('SELECT GET_LOCK('
                                        . "'${seqname}_lock', 10)");
				if(is_null($result))
				{
					return false;
				}

				if($result == 0)
				{
					return false;
				}

             	$result = $this->query('REPLACE INTO ' . $seqname
                                       . ' (id) VALUES (0)');

             	if(!$result)
             	{
                	return false;
				}

             	$result = $this->fetchOne('SELECT RELEASE_LOCK('
                                        . "'${seqname}_lock')");

              	if(!$result)
              	{
              		return false;
              	}
             	return 1;

            } else
            {

            	$result = $this->createSequence($seqname);




                if($result === false)
                {
                	return false;
                }
                else
                {
                	return 1;
                }

	        }

        } while ($repeat);


    }


    public function createSequence($sequenceName)
    {
        $phrase = "CREATE TABLE {$sequenceName} (id integer UNSIGNED AUTO_INCREMENT NOT NULL, primary key(id))";
        $query = $this->query($phrase);
        $this->query("INSERT INTO {$sequenceName} (id) VALUES (0)");
        return 1;
    }

    
    
    public function formatFieldForSQL(Lead_EDO_Datatype_Field_Value $field)
	{
	    if($field->getType() == 'Boolean') {
	        return ($field->getValue() === true) ? 1 : 0;
	    }
	    
	    return $field->getValue();
	    
	}
    

}
